package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"time"

	"gitee.com/iguojin/gopost/httpclient"
	"github.com/go-resty/resty/v2"
)

type Config struct {
	Url      string            `json:"url"`
	Method   string            `json:"method"`
	Debug    bool              `json:"debug"`
	Json     any               `json:"json"`
	Query    map[string]string `json:"query"`
	Headers  map[string]string `json:"headers"`
	Body     map[string]string `json:"body"`
	FormData map[string]any    `json:"form_data"`
	Timeout  int               `json:"timeout"`
}

var config Config

func prettyPrint(src []byte) {
	var prettyJSON bytes.Buffer
	err := json.Indent(&prettyJSON, src, "", "\t")
	// 无法解析则展示文本
	if err != nil {
		fmt.Println(string(src))
		return
	}

	fmt.Println("\n" + prettyJSON.String())
}

func loadConfig(b []byte) {
	if err := json.Unmarshal(b, &config); err != nil {
		log.Fatalf("解析错误: %s", err.Error())
		return
	}
	if config.Timeout == 0 {
		config.Timeout = 60
	}
	if config.Method == "" {
		config.Method = http.MethodGet
	}
	config.Method = strings.ToUpper(config.Method)
}

func handlePostGet() {
	client := httpclient.New()
	req := client.
		SetTimeout(time.Duration(config.Timeout) * time.Second).
		SetDebug(config.Debug).
		R()

	// query
	req.SetQueryParams(config.Query)

	// header
	for k, v := range config.Headers {
		req.SetHeader(k, v)
	}
	if config.Method == http.MethodPost {
		// 这里对form_data支持有问题,必须输入已经编码好的数据,优先使用json
		if len(config.FormData) != 0 {
			req.SetHeader("Content-Type", "application/x-www-form-urlencoded")
			req.SetBody(config.FormData)
		} else {
			req.SetHeader("Content-Type", "application/json")
			req.SetBody(config.Json)
		}
	}

	var (
		resp *resty.Response
		err  error
	)

	reqUrl := config.Url
	if config.Method == http.MethodPost {
		resp, err = req.Post(reqUrl)
	} else {
		resp, err = req.Get(reqUrl)
	}
	if err != nil {
		panic(err)
	}

	// body
	body := resp.Body()

	// print
	if strings.Contains(resp.Header().Get("Content-Type"), "json") {
		prettyPrint(body)
		return
	}
	fmt.Println(string(body))
}

func main() {
	if len(os.Args) < 2 {
		log.Fatalln("无文件路径")
		return
	}

	jsonPath := os.Args[1]
	b, err := os.ReadFile(jsonPath)
	if err != nil {
		log.Fatalf("读文件错误: %s", err.Error())
		return
	}

	loadConfig(b)
	handlePostGet()
}
